﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WheelChairSimulation2
{
    class Track : SimEnvironment
    {
        //WheelChair wheelChair;

        ////private float cameraPosition;
        //private Vector2 cameraPosition;
        //// Key locations in the level.        
        //private Vector2 start;
        //private Point exit = InvalidPosition;
        //private static readonly Point InvalidPosition = new Point(-1, -1);
        //private float elapsedTime;
        //public ContentManager content;
        //private int envWidth = 3000;
        //private int envHeight = 1000;
        List<Items> parkBenches = new List<Items>();
        Items parkFence;
        public Texture2D item;
        public Vector2 itemPosition;
        public Texture2D track;
        Color[,] trackColorArray;
        Color[,] wheelChairColorArray;
        Matrix trackMatrix;
        Matrix wheelChairMatrix;
        
        public Track(IServiceProvider serviceProvider, string path)
        {
            content = new ContentManager(serviceProvider, "Content");
            item = content.Load<Texture2D>("WhiteBox");
            parkBenches.Add(new Items(item, 100, 100));
            
            item = content.Load<Texture2D>("BrownRectangle");
            parkFence = new Items(item, 0, 500);
            //item = content.Load<Texture2D>("Path");
            //parkBenches.Add(new Items(item, 500, 100));
            track = content.Load<Texture2D>("track");

            itemPosition.X = 5;
            itemPosition.Y = 50;
            //base.co1tent = content;
            //start.X = 575;
            //start.Y = 175;
            start.X = 275;
            start.Y = 775;
            envWidth = 3000;
            envHeight = 1000;
            wheelChair = new WheelChair(this, start);
            cameraPosition.X = 0.0f;
            cameraPosition.Y = 0.0f;
            elapsedTime = 0.0f;
            trackColorArray = TextureTo2DArray(track);
            trackMatrix = Matrix.CreateTranslation(0.0f, 0.0f, 0) * Matrix.CreateScale(1.5f) * Matrix.CreateTranslation(itemPosition.X, itemPosition.Y, 0) * Matrix.Identity;
            wheelChairColorArray = TextureTo2DArray(wheelChair.wheelChairTexture);
            wheelChairMatrix = Matrix.CreateTranslation(start.X, start.Y, 0) * Matrix.Identity;
        }
        public override void LoadEnvironment()
        {
            
            //base.LoadEnvironment(environment);
        }

        public override void Update(GameTime gameTime)
        {
            Vector2 previousPoint = wheelChair.Position;
            wheelChair.Update(gameTime);
            Vector2 collisionPoint = CheckPlayerCollision();
            if (collisionPoint.X > -1 || collisionPoint.Y > -1)
                wheelChair.Position = previousPoint;
        }

        private Vector2 CheckPlayerCollision()
        {
            wheelChairMatrix = Matrix.CreateTranslation(wheelChair.Position.X, wheelChair.Position.Y, 0);

            Vector2 collisionPoint = TexturesCollide(wheelChairColorArray, wheelChairMatrix, trackColorArray, trackMatrix);

            if (collisionPoint.X > -1 || collisionPoint.Y > -1)
                return collisionPoint;


            return new Vector2(-1, -1);
        }

        private Vector2 TexturesCollide(Color[,] tex1, Matrix mat1, Color[,] tex2, Matrix mat2)
        {
            Matrix mat1to2 = mat1 * Matrix.Invert(mat2);
            int width1 = tex1.GetLength(0);
            int height1 = tex1.GetLength(1);
            int width2 = tex2.GetLength(0);
            int height2 = tex2.GetLength(1);

            for (int x1 = 0; x1 < width1; x1++)
            {
                for (int y1 = 0; y1 < height1; y1++)
                {
                    Vector2 pos1 = new Vector2(x1, y1);
                    Vector2 pos2 = Vector2.Transform(pos1, mat1to2);

                    int x2 = (int)pos2.X;
                    int y2 = (int)pos2.Y;
                    if ((x2 >= 0) && (x2 < width2))
                    {
                        if ((y2 >= 0) && (y2 < height2))
                        {
                            if (tex1[x1, y1].A > 0)
                            {
                                if (tex2[x2, y2].A <= 0)
                                {
                                    Vector2 screenPos = Vector2.Transform(pos1, mat1);
                                    return screenPos;
                                }
                            }
                        }
                    }
                }
            }

            return new Vector2(-1, -1);
        }

        private Color[,] TextureTo2DArray(Texture2D texture)
        {
            Color[] colors1D = new Color[texture.Width * texture.Height];
            texture.GetData(colors1D);

            Color[,] colors2D = new Color[texture.Width, texture.Height];
            for (int x = 0; x < texture.Width; x++)
                for (int y = 0; y < texture.Height; y++)
                    colors2D[x, y] = colors1D[x + y * texture.Width];

            return colors2D;
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            ScrollCamera(spriteBatch.GraphicsDevice.Viewport);
            Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition.X, -cameraPosition.Y, 0.0f);
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default,
                              RasterizerState.CullCounterClockwise, null, cameraTransform);



            //spriteBatch.Draw(track, new Vector2(50, 100), Color.White);
            spriteBatch.Draw(track, new Vector2(itemPosition.X, itemPosition.Y), null, Color.White, 0.0f, new Vector2(0.0f, 0.0f), 1.5f, SpriteEffects.None, 0.0f); 
            wheelChair.Draw(spriteBatch);
            spriteBatch.End();
        }

        private void ScrollCamera(Viewport viewport)
        {
            const float ViewMargin = .35f;
            const float ViewMarginY = .25f;
            float Margin = viewport.Width * ViewMargin;
            float MarginY = viewport.Height * ViewMarginY;
            float leftMargin = cameraPosition.X + Margin;
            float rightMargin = cameraPosition.X + viewport.Width - Margin;
            float topMargin = cameraPosition.Y + MarginY;
            float bottomMargin = cameraPosition.Y + viewport.Height - MarginY;
            float cameraMovement = 0.0f;
            float cameraMovementY = 0.0f;

            if (wheelChair.Position.X < leftMargin)
            {
                cameraMovement = wheelChair.Position.X - leftMargin;
            }
            else if (wheelChair.Position.X > rightMargin)
            {
                cameraMovement = wheelChair.Position.X - rightMargin;
                //GrassNbr = 2;
            }

            if (wheelChair.Position.Y < topMargin)
            {
                cameraMovementY = wheelChair.Position.Y - topMargin;
            }
            else if (wheelChair.Position.Y > bottomMargin)
            {
                cameraMovementY = wheelChair.Position.Y - bottomMargin;
                //GrassNbr = 2;
            }


            float MaxCameraPosition = 2 * viewport.Width;
            float MaxCameraPositionY = 2 * viewport.Height;
            cameraPosition.X = MathHelper.Clamp(cameraPosition.X + cameraMovement, 0.0f, MaxCameraPosition);
            cameraPosition.Y = MathHelper.Clamp(cameraPosition.Y + cameraMovementY, 0.0f, MaxCameraPositionY);

            // healthBarPos.X = MathHelper.Clamp(healthBarPos.X + cameraMovement, 25.0f, MaxCameraPostion);
        }
        void drawFence(SpriteBatch spriteBatch)
        {
            Vector2 startPosition = parkFence.itemPosition;
            
            //Vector2 startPosition2 = parkFence.itemPosition.X +
            for (int i = 0; i <= 12; i++)
            {
                if (i < 6)
                {
                    spriteBatch.Draw(parkFence.item, startPosition, Color.White);
                    startPosition.Y = startPosition.Y - 100;
                }
                else if (i == 6)
                {
                    startPosition.X = startPosition.X + 1170;
                }
                else if (i >= 6)
                {
                    startPosition.Y = startPosition.Y + 100;
                    spriteBatch.Draw(parkFence.item, startPosition, Color.White);         
                }
            }
            //spriteBatch.Draw(parkFence.item, parkFence.itemPosition,
        }
    }
}
